import { Injectable } from '@angular/core';
import {Student} from './student';
import {Observable, of} from 'rxjs';
import {MessageService} from './message.service';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {catchError, map, tap} from 'rxjs/operators';
const httpOptions = {
  headers: new HttpHeaders({'Content-Type': 'application/json'})
};

@Injectable({
  providedIn: 'root'
})
export class StudentService {
  public studentsUrl = '/stubasicinfo';


  constructor( private http: HttpClient, private messageService: MessageService) { }
  getStudents(): Observable<any> {
    return this.http.get('/stubasicinfo')
      .pipe(
        tap(_ => this.log('获取所有学生信息')),
        catchError(this.handleError<Student[]>('getStudents', []))
      );
  }
  getStudent(id: string): Observable<Student> {
    const url = `${this.studentsUrl}/${id}`;
    return this.http.get<Student>(url).pipe(
      tap(_ => this.log( `获取学生信息，学号为${id}` )),
      catchError(this.handleError<Student>(`getStudent id=${id}`))
    );
  }
  private log(message: string) {
    this.messageService.add(`StudentService:${message}`);
  }
  updateStudent(student: Student): Observable<any> {
    return this.http.put(this.studentsUrl, student, httpOptions).pipe(
      tap(_ => this.log(`更新了学生信息，学号为${student.stuid}`)),
      catchError(this.handleError<any>('updateStudent'))
    );
  }
  addStudent(student: Student): Observable<Student> {
    return this.http.post<Student>(this.studentsUrl, student, httpOptions).pipe(
      tap((newStudent: Student) => this.log(`添加新学生信息,学号为${newStudent.stuid}`)),
      catchError(this.handleError<Student>('addStudent'))
    );
  }
  deleteStudent(student: Student | string): Observable<Student> {
    const id = typeof student === 'string' ? student : student.stuid;
    const url = `${this.studentsUrl}/${id}`;

    return this.http.delete<Student>(url, httpOptions).pipe(
      tap(_ => this.log(`deleted hero id=${id}`)),
      catchError(this.handleError<Student>('deleteHero'))
    );
  }
  searchStudents(term: string): Observable<Student[]> {
    if (!term.trim()) {
      return of([]);
    }
    return this.http.get<Student[]>(`${this.studentsUrl}/?studentName=${term}`).pipe(
      tap(x => x.length ?
        this.log(`发现姓名为"${term}"的学生。`) :
        this.log(`没有学生匹配姓名"${term}"`),
        catchError(this.handleError<Student[]>('searchStudents', []))
      ));
  }


  /**
   * Handle Http operation that failed.
   * Let the app continue.
   * @param operation - name of the operation that failed
   * @param result - optional value to return as the observable result
   */
  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      // TODO: send the error to remote logging infrastructure
      console.error(error); // log to console instead

      // TODO: better job of transforming error for user consumption
      this.log(`${operation} failed: ${error.message}`);

      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }
}

